#include <stdio.h>
#include <unistd.h>
#include "ohos_init.h"
#include "cmsis_os2.h"

#include <unistd.h>
#include "hi_wifi_api.h"
//#include "wifi_sta.h"
#include "lwip/ip_addr.h"
#include "lwip/netifapi.h"
#include "lwip/sockets.h"

#include "MQTTPacket.h"
#include "transport.h"

#include "uart_cli_simple_api.h"

int toStop = 0;

#if defined(MQTT_CLIENT_ENABLE) && (MQTT_CLIENT_ENABLE == 1)
#define SEND_DATA_MAX_LENGTH   200
char send_to_mqtt[SEND_DATA_MAX_LENGTH] = {0x00,};
char user_ip[16] = {0x00,};
char user_port[5] = {0x00,};

int mqtt_connect_test(void)
{
	MQTTPacket_connectData data = MQTTPacket_connectData_initializer;
	int rc = 0;
	int mysock = 0;
	unsigned char buf[200];
	int buflen = sizeof(buf);
	int msgid = 1;
	MQTTString topicString = MQTTString_initializer;
	int req_qos = 0;
	char* payload = "hello HarmonyOS";
	int payloadlen = strlen(payload);
	int len = 0;
    char *host = "192.168.1.1"; //小邹的mqtt ip
	//char *host = "106.13.62.194";
    //char *host = "192.168.1.102";
	hi_u16 mqtt_port = 1883;


	mysock = transport_open(host, mqtt_port);
	if(mysock < 0)
		return mysock;

	printf("Sending to hostname %s port %d\n", host, mqtt_port);

	data.clientID.cstring = "hisi_mqtt_c";
	data.keepAliveInterval = 20;
	data.cleansession = 1;
	//data.username.cstring = "testuser";
	//data.password.cstring = "testpassword";
	data.username.cstring = "protea111";
	data.password.cstring = "12345678";

	len = MQTTSerialize_connect(buf, buflen, &data);
	rc = transport_sendPacketBuffer(mysock, buf, len);

	/* wait for connack */
	if (MQTTPacket_read(buf, buflen, transport_getdata) == CONNACK)
	{
		unsigned char sessionPresent, connack_rc;

		if (MQTTDeserialize_connack(&sessionPresent, &connack_rc, buf, buflen) != 1 || connack_rc != 0)
		{
			printf("Unable to connect, return code %d\n", connack_rc);
			goto exit;
		}
	}
	else
		goto exit;

	/* subscribe 订阅*/
	topicString.cstring = "substopic";
	len = MQTTSerialize_subscribe(buf, buflen, 0, msgid, 1, &topicString, &req_qos);
	rc = transport_sendPacketBuffer(mysock, buf, len);
	if (MQTTPacket_read(buf, buflen, transport_getdata) == SUBACK) 	/* wait for suback */
	{
		unsigned short submsgid;
		int subcount;
		int granted_qos;

		rc = MQTTDeserialize_suback(&submsgid, 1, &subcount, &granted_qos, buf, buflen);
		if (granted_qos != 0)
		{
			printf("granted qos != 0, %d\n", granted_qos);
			goto exit;
		}
	}
	else
		goto exit;

	/* loop getting msgs on subscribed topic 循环获取订阅主题的消息*/
	topicString.cstring = "pubtopic";
	while (!toStop)
	{
		/* transport_getdata() has a built-in 1 second timeout,
		your mileage will vary */
		if (MQTTPacket_read(buf, buflen, transport_getdata) == PUBLISH)
		{
			unsigned char dup;
			int qos;
			unsigned char retained;
			unsigned short msgid;
			int payloadlen_in;
			unsigned char* payload_in;
			int rc;
			MQTTString receivedTopic;
			rc = MQTTDeserialize_publish(&dup, &qos, &retained, &msgid, &receivedTopic,
					&payload_in, &payloadlen_in, buf, buflen);
			printf("message arrived %.*s\n", payloadlen_in, payload_in);

            rc = rc;
        }

		printf("publishing reading\n");
		len = MQTTSerialize_publish(buf, buflen, 0, 0, 0, 0, topicString, (unsigned char*)payload, payloadlen);
        rc = transport_sendPacketBuffer(mysock, buf, len);
	}

	printf("disconnecting\n");
	len = MQTTSerialize_disconnect(buf, buflen);
	rc = transport_sendPacketBuffer(mysock, buf, len);
exit:
	transport_close(mysock);

    rc = rc;

	return 0;
}

int mqtt_connect_to(char* mqtt_ip, char* mqtt_port_c)
{
	hi_u16 port = atoi(mqtt_port_c);
    CHECK_PARAM_INT("port", port);

	MQTTPacket_connectData data = MQTTPacket_connectData_initializer;
	int rc = 0;
	int mysock = 0;
	unsigned char buf[200];
	int buflen = sizeof(buf);
	int msgid = 1;
	MQTTString topicString = MQTTString_initializer;
	int req_qos = 0;
	char* payload = "hello HarmonyOS";
	//int payloadlen = strlen(payload);
	int len = 0;
    char *host = mqtt_ip; //小邹的mqtt ip
	//char *host = "106.13.62.194";
    //char *host = "192.168.1.102";
	hi_u16 mqtt_port = port;

	mysock = transport_open(host, mqtt_port);
	if(mysock < 0)
		return mysock;

	printf("Sending to hostname %s port %d\n", host, mqtt_port);

	data.clientID.cstring = "hisi_mqtt_c";
	data.keepAliveInterval = 20;
	data.cleansession = 1;
	data.username.cstring = "protea111";   //在产线烧写如flash，然后上电读取--三方认证，最为安全
	data.password.cstring = "12345678";    //在产线烧写如flash，然后上电读取--三方认证，最为安全

	len = MQTTSerialize_connect(buf, buflen, &data);
	rc = transport_sendPacketBuffer(mysock, buf, len);

	/* wait for connack */
	if (MQTTPacket_read(buf, buflen, transport_getdata) == CONNACK)
	{
		unsigned char sessionPresent, connack_rc;

		if (MQTTDeserialize_connack(&sessionPresent, &connack_rc, buf, buflen) != 1 || connack_rc != 0)
		{
			printf("Unable to connect, return code %d\n", connack_rc);
			goto exit;
		}
	}
	else
		goto exit;

#if 1
	/* subscribe 订阅*/
	topicString.cstring = "substopic";
	len = MQTTSerialize_subscribe(buf, buflen, 0, msgid, 1, &topicString, &req_qos);
	rc = transport_sendPacketBuffer(mysock, buf, len);
	if (MQTTPacket_read(buf, buflen, transport_getdata) == SUBACK) 	/* wait for suback */
	{
		unsigned short submsgid;
		int subcount;
		int granted_qos;

		rc = MQTTDeserialize_suback(&submsgid, 1, &subcount, &granted_qos, buf, buflen);
		if (granted_qos != 0)
		{
			printf("granted qos != 0, %d\n", granted_qos);
			goto exit;
		}
	}
	else
		goto exit;

	/* loop getting msgs on subscribed topic 循环获取订阅主题的消息*/
	topicString.cstring = "pubtopic_112233";//+mac地址
	while (!toStop)
	{
		/* transport_getdata() has a built-in 1 second timeout,
		your mileage will vary */
		if (MQTTPacket_read(buf, buflen, transport_getdata) == PUBLISH)
		{
			unsigned char dup;
			int qos;
			unsigned char retained;
			unsigned short msgid;
			int payloadlen_in;
			unsigned char* payload_in;
			int rc;
			MQTTString receivedTopic;
			rc = MQTTDeserialize_publish(&dup, &qos, &retained, &msgid, &receivedTopic,
					&payload_in, &payloadlen_in, buf, buflen);
			printf("message arrived %.*s\n", payloadlen_in, payload_in);

            rc = rc;
        }

		//printf("publishing reading\n");
		//将payload推送到mqtt服务器上的pubtopic主题
		if(send_to_mqtt[0] != 0x00)
		{
			int send_len = strlen(payload);
			len = MQTTSerialize_publish(buf, buflen, 0, 0, 0, 0, topicString, (unsigned char*)send_to_mqtt, send_len);
			rc = transport_sendPacketBuffer(mysock, buf, len);
			(hi_void)hi_sleep(100); //wait 
			memset(send_to_mqtt, 0x00, SEND_DATA_MAX_LENGTH);
			printf("publishing reading\n");
		}
		(hi_void)hi_sleep(100); //wait 
		//len = MQTTSerialize_publish(buf, buflen, 0, 0, 0, 0, topicString, (unsigned char*)payload, payloadlen);
        //rc = transport_sendPacketBuffer(mysock, buf, len);
	}

	printf("disconnecting\n");
	len = MQTTSerialize_disconnect(buf, buflen);
	rc = transport_sendPacketBuffer(mysock, buf, len);
exit:
	transport_close(mysock);
#endif

    rc = rc;

	return 0;
}



void mqtt_test(void)
{
    mqtt_connect_test();
}

void mqtt_send_to_service(char* param)
{
	strcpy(send_to_mqtt, param);
}

static void MQTTConnectTask(void *arg)
{
	(void)arg;
	mqtt_connect_to(user_ip, user_port);
}

void mqtt_connect_task_creat(void)
{
    osThreadAttr_t attr;

    attr.name = "MQTTConnectTask";
    attr.attr_bits = 0U;
    attr.cb_mem = NULL;
    attr.cb_size = 0U;
    attr.stack_mem = NULL;
    attr.stack_size = 3000;
    attr.priority = osPriorityNormal1;

    if (osThreadNew(MQTTConnectTask, NULL, &attr) == NULL) {
        cli_printf("Falied to create MQTTConnectTask!\n");
    }
    else
    {
        cli_printf("start to create MQTTConnectTask!\n");
    }
}

void mqtt_client_connect_to_serv(char* mqtt_ip, char* mqtt_port)
{
    strcpy(user_ip, mqtt_ip);
	strcpy(user_port, mqtt_port);
	mqtt_connect_task_creat();
}
#endif